package Webpacus::Controller::Editor;

use strict;
use warnings;
use base 'Catalyst::Controller';

use HTML::Tidy;

=head1 NAME

Webpacus::Controller::Editor - AJAX template and CSS editor

=head1 SYNOPSIS

See L<Webpacus>, L<WebPAC>

=head1 DESCRIPTION

Catalyst Controller.

=head1 METHODS

=over 4

=item default

=cut

sub default : Private {
	my ( $self, $c ) = @_;

	my $webpac = $c->comp('Model::WebPAC');
	my $params = $c->req->params;
	my $log = $c->log;

	my $template_filename = 
		$c->req->params->{template_filename} ||
		$c->config->{webpac}->{default_template} ||
		$c->log->fatal("need default_template");

	$c->stash->{template_filename} = $template_filename;

	$c->stash->{template} = 'editor.tt';
}

=item template

fetch template using C<template_filename> in request or
C<< webpac->default_template >>.

=cut

sub template : Local {
	my ( $self, $c ) = @_;

	my $template_filename = 
		$c->req->params->{template_filename} ||
		$c->config->{webpac}->{default_template} ||
		$c->log->fatal("need default_template");

	my $webpac = $c->comp('Model::WebPAC');

	my $template_path = $webpac->{template_path} || $c->log->fatal("can't find template_path in Model::WebPAC");

	my $template_full_path = "$template_path/$template_filename";

	if ($c->req->params->{save_template}) {

		$c->response->content_type('text/html; charset=utf-8'); 

		my $t = $c->req->params->{template_content};
		my $size = length($t);
		$c->log->debug("saving $template_full_path, $size bytes");
		if ($webpac->save_html( $template_full_path, $t )) {
			$c->res->output("<span>saved $template_filename, $size bytes</span>");
		} else {
			$c->res->output("<span class=\"error\">error saving $template_filename!</span>");
		}
		return;
	}

	$c->log->debug("loading $template_full_path");

	if (! -r $template_full_path) {
		$c->log->warn("can't find '$template_full_path': $!");
		$c->response->content_type('text/html; charset=utf-8'); 
		$c->res->output("can't find template '$template_full_path'");
		return;
	}

	# load template html
	$c->stash->{'template_content'} =
		$webpac->load_html( $template_full_path );

	# load template list

	opendir(my $d, $template_path) || $c->log->fatal("can't opendir '$template_path': $!");
	my @templates = grep { /\.tt$/i } readdir($d);

	$c->stash->{template_list} = \@templates;
	$c->stash->{template_filename} = $template_filename;

	$c->stash->{template} = 'editor/template.tt';
}

=item css

Return css.

B<Not finished>

=cut

sub css : Local {
	my ( $self, $c ) = @_;

	my $css_filename = $c->config->{webpac}->{default_css} || die("need default_css");
	my $css_path = $c->config->{webpac}->{css_path} || die("need css_path");
	my $webpac = $c->comp('Model::WebPAC');

	my $css_full_path = "$css_path/$css_filename";

	if ($c->req->params->{save_css}) {

		$c->response->content_type('text/html; charset=utf-8'); 

		my $t = $c->req->params->{css_content};
		my $size = length($t);
		$c->log->debug("saving $css_full_path, $size bytes");
		if ($webpac->save_html( $css_full_path, $t )) {
			$c->res->output("<span>saved $css_filename, $size bytes</span>");
		} else {
			$c->res->output("<span class=\"error\">error saving $css_filename!</span>");
		}
		return;
	}

	$c->log->debug("loading $css_full_path");

	$c->stash->{'css_content'} = $webpac->load_html( $css_full_path );

	$c->stash->{'css_list'} = [ qw/user.css foobar.css/ ];

	$c->stash->{template} = 'editor/css.tt';
}

=item record

Return html of record taking C<mfn> and C<template_filename> from request.

=cut

sub record : Local {
	my ( $self, $c ) = @_;

	$c->log->dumper($c->req->params, 'params');

	my $record_uri = $c->req->params->{record_uri};
	$record_uri ||= $c->config->{editor}->{default_record_uri} and
		$c->log->warn("using editor: default_record_uri");

	if (! $record_uri) {
		$c->log->fatal("record called without record_uri and default_record_uri not found in config under editor");
		$c->stash->{error} = 'record retrival failed';
		$c->stash->{template} = 'error.tt';
		return;
	}

	my $template_filename = $c->req->params->{template_filename};
	if (! $template_filename) {
		$template_filename = $c->config->{webpac}->{default_template} || $c->log->fatal("no webpac->default_template in configuration!");
		$c->log->warn("no template_filename using $template_filename");
	}

	my $webpac = $c->comp('Model::WebPAC');

	my $html = $webpac->record( record_uri => $record_uri, template => $template_filename );

	if ($html) {
		$c->log->debug('check html with tidy');
		my $tidy = new HTML::Tidy;
		$tidy->ignore( text => [
			qr/DOCTYPE/, qr/unsupported/, qr/proprietary/i,
			qr/invalid character code/,
			qr/inserting missing 'title' element/,
			qr/lacks "summary" attribute/,
		] );

		my @lines = split( "\n", $html );
		$_ = "$_\n" for @lines;

		if ( $tidy->parse('tidy', @lines) ) {
			if ( $tidy->messages ) {
				$html .= <<__TIDY_CLOSE__;
<div id="tidy_show" class="notice" style="display: none;" onclick="Element.hide('tidy_show'); Element.show('tidy');">?</div>
<div id="tidy" class="tidy">
<a href="#" onclick="Element.hide('tidy'); Element.show('tidy_show'); return false;">close</a>
HTML Tidy output:
<br/>
__TIDY_CLOSE__
				# Escape <, >, & and ", and to produce valid XML
				my %escape = ('<'=>'&lt;', '>'=>'&gt;', '&'=>'&amp;', '"'=>'&quot;');
				my $escape_re  = join '|' => keys %escape;

				foreach my $m ( $tidy->messages ) {
					my $c = $lines[ ( $m->line - 1 ) ];
					my $txt = $m->as_string;
					$c =~ s/($escape_re)/$escape{$1}/g;
					$txt =~ s/($escape_re)/$escape{$1}/g;
					my $class = '';
					$class = ' class="tidy_'.lc($1).'"' if ($txt =~ /(Warning|Error):/s);
					$html .= 'line ' . $m->line . ":<span${class}>$txt<tt>$c</tt></span>";
				}
				$html .= '</div>';
			}
		} else {
			$html .= qq{<div class="tidy tidy_error">Can't parse this record with HTML Tidy!</div>};
		}
	} else {
		$html .= qq{<div class="no_results">Can't find record $record_uri</div>};
	}

	$c->response->content_type('text/html; charset=utf-8'); 
	$c->response->body( $html );
}



=back

=head1 AUTHOR

Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>

=head1 LICENSE

This library is free software, you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;
